package generate

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/golang/protobuf/protoc-gen-go/generator"
)

type DBConfig struct {
	User     string
	Password string
	Host     string
	Port     string
	Database string
	MaxIdle  int
	MaxOpen  int
	MaxLife  time.Duration
}

func GenertateTable(tableNames ...string) {
	tableNamesStr := ""
	for _, name := range tableNames {
		if tableNamesStr != "" {
			tableNamesStr += ","
		}
		tableNamesStr += "'" + name + "'"
	}
	// 生成所有表信息
	tables := getTables(tableNamesStr)
	log.Printf("tables=%s\n", tables)
	for _, table := range tables {
		fields := getFields(table.Name)
		generateModel(table, fields)
	}
}

// 生成Model
func generateModel(table Table, fields []Field) {
	content := "package models\n\n"
	// 表注释
	if len(table.Comment) > 0 {
		content += "// " + table.Comment + "\n"
	}
	content += "type " + generator.CamelCase(table.Name) + " struct {\n"
	// 生成字段
	for _, field := range fields {
		// log.Printf(">>>>>>>>>>>>>>>>>>field=%+v\n", field)
		fieldName := generator.CamelCase(strings.ToLower(field.Field))
		// log.Printf("fieldName=%v ,field.Field= %s", fieldName, field.Field)
		// fieldName := Case2Camel(field.Field)
		// 根据字段 获取对应的字段的类型
		fieldType := getFiledType(field)
		// 根据字段 获取对应的字段的Orm 表字段信息
		fieldOrm := getFieldOrm(field)
		// 根据字段 获取对应的JSON tag 信息
		fieldJson := getFieldJson(field)
		// 根据字段  获取对应的备注信息
		fieldComment := getFieldComment(field)
		content += "	" + fieldName + " " + fieldType + " `" + fieldOrm + " " + fieldJson + "` " + fieldComment + "\n"
	}
	content += "}\n\n"

	// 生成 对应的表名称
	content += "func (" + FirstLower(generator.CamelCase(table.Name)) + " *" + generator.CamelCase(table.Name) + ") TableName() string {\n"
	content += "	return " + fmt.Sprintf("%s%s%s", "\"", table.Name, "\"") + "\n"
	content += "}\n\n"

	// 生成CRUD方法
	content += "// Create 创建记录\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") Create() error {\n"
	content += "	 \n"
	content += "	return  Db.Create(m).Error\n"
	content += "}\n\n"

	content += "// CreateInBatches 批量创建记录\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") CreateInBatches(models []" + generator.CamelCase(table.Name) + ", batchSize int) error {\n"
	content += "	 \n"
	content += "	return  Db.CreateInBatches(models, batchSize).Error\n"
	content += "}\n\n"

	content += "// Update 更新记录\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") Update() error {\n"
	content += "	 \n"
	content += "	return  Db.Model(m).Updates(m).Error\n"
	content += "}\n\n"

	content += "// Delete 删除记录\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") Delete(where map[string]interface{}) error {\n"
	content += "	 \n"
	content += "	for field, value := range where {\n"
	content += "		Db =  Db.Where(field+\" = ?\", value)\n"
	content += "	}\n"
	content += "	return  Db.Delete(m).Error\n"
	content += "}\n\n"

	content += "// BatchDelete 批量删除\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") BatchDelete(ids []interface{}) error {\n"
	content += "	 \n"
	content += "	return  Db.Where(\"" + fields[0].Field + " IN (?)\", ids).Delete(m).Error\n"
	content += "}\n\n"

	content += "// 全部数据查询\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") FindAll() ([]Person, error) {\n"
	content += "	var results []Person \n"
	content += " if err := Db.Find(&results).Error; err != nil {\n"
	content += "	return nil, err\n"
	content += " }\n"
	content += "	return results, nil\n"
	content += "}\n\n"

	content += "// FindByField 根据字段查询\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") FindByField(field string, value interface{}) ([]" + generator.CamelCase(table.Name) + ", error) {\n"
	content += "	var results []" + generator.CamelCase(table.Name) + "\n"
	content += "	 \n\n"
	content += "	switch field {\n"
	for _, field := range fields {
		fieldName := generator.CamelCase(strings.ToLower(field.Field))
		content += "	case \"" + fieldName + "\":\n"
		content += "		Db =  Db.Where(\"" + field.Field + " = ?\", value)\n"
	}
	content += "	default:\n"
	content += "		return nil, errors.New(\"invalid field name\")\n"
	content += "	}\n\n"
	content += "	if err :=  Db.Find(&results).Error; err != nil {\n"
	content += "		return nil, err\n"
	content += "	}\n"
	content += "	return results, nil\n"
	content += "}\n\n"

	content += "// FindPage 分页查询\n"
	content += "func (m *" + generator.CamelCase(table.Name) + ") FindPage(page, size int, where map[string]interface{}) ([]" + generator.CamelCase(table.Name) + ", int64, error) {\n"
	content += "	var results []" + generator.CamelCase(table.Name) + "\n"
	content += "	var total int64\n"
	content += "	 \n\n"
	content += "	for field, value := range where {\n"
	content += "		Db =  Db.Where(field+\" = ?\", value)\n"
	content += "	}\n\n"
	content += "	if err :=  Db.Model(m).Count(&total).Offset((page - 1) * size).Limit(size).Find(&results).Error; err != nil {\n"
	content += "		return nil, 0, err\n"
	content += "	}\n"
	content += "	return results, total, nil\n"
	content += "}\n\n"

	filename := generator.CamelCase(table.Name) + ".go"
	makeFile(content, filename)
	log.Println(generator.CamelCase(table.Name) + " 已生成...")

}
